package com.touchstone.pacs.common.utils;

import com.alibaba.fastjson.JSONObject;
import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.ParseException;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * @Description : 网络连接工具类(基于httpClient)
 * @Author : hugo
 * @Date: 2019-05-08 21:56
 * @Version: 1.0
 **/
public class HttpUtils {

    /**
     * 功能描述: get方式请求，无参数的情况
     *
     * @param url 地址
     * @return
     * @throws
     * @author hugo
     * @date 2019/5/8 22:30
     */
    public static String get(String url) {
        return doGet(url, "");
    }

    /**
     * 功能描述: get方式请求，无参数的情况
     *
     * @param url   地址
     * @param param 参数
     * @return
     * @throws
     * @author hugo
     * @date 2019/5/8 22:31
     */
    public static String get(String url, Map<String, Object> param) {
        // 参数map2String
        return doGet(url, map2String(param));
    }

    /**
     * 功能描述: post方式请求，无参数的情况
     *
     * @param url 地址
     * @return
     * @throws
     * @author hugo
     * @date 2019/5/8 22:31
     */
    public static String post(String url) {
        return doPost(url, "");
    }

    /**
     * 功能描述: post方式请求，有参数拼接在地址栏的情况
     *
     * @param url   地址
     * @param param 参数
     * @return
     * @throws
     * @author hugo
     * @date 2019/5/8 22:31
     */
    public static String postUrlParm(String url, Map<String, Object> param) {
        return doPost(url, map2String(param));
    }

    /**
     * 功能描述: post方式请求，对象参数的情况
     *
     * @param url   地址
     * @param param 参数
     * @return
     * @throws
     * @author hugo
     * @date 2019/5/8 22:43
     */
    public static String postObject(String url, Map<String, Object> param) {
        return doPost(url, param);
    }

    /**
     * 功能描述: post方式请求，复杂参数的情况
     *
     * @param url   地址
     * @param jsonObject 参数
     * @return
     * @throws
     * @author hugo
     * @date 2019/5/8 22:43
     */
    public static String postJson(String url, JSONObject jsonObject) {
        return doPostJson(url, jsonObject);
    }


    private static String doGet(String url, String params) {
        // 获得Http客户端(可以理解为:你得先有一个浏览器;注意:实际上HttpClient与浏览器是不一样的)
        CloseableHttpClient httpClient = HttpClientBuilder.create().build();
        // 创建Get请求
        if (params != null && !"".equals(params.trim())) {
            url = (url.startsWith("http") ? url : "http://" + url) + "?" + params;
        }
        System.out.println("url:" + url);
        HttpGet httpGet = new HttpGet(url);
        // 响应模型
        CloseableHttpResponse response = null;
        String result = "";
        try {
            // 配置信息
            RequestConfig requestConfig = RequestConfig.custom()
                    // 设置连接超时时间(单位毫秒)
                    .setConnectTimeout(5000)
                    // 设置请求超时时间(单位毫秒)
                    .setConnectionRequestTimeout(5000)
                    // socket读写超时时间(单位毫秒)
                    .setSocketTimeout(5000)
                    // 设置是否允许重定向(默认为true)
                    .setRedirectsEnabled(true).build();

            //设置请求头消息User-Agent
            httpGet.setHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36");
            httpGet.setHeader("Host", "www.95598.cn");
            httpGet.setHeader("Connection", "keep-alive");
            httpGet.setHeader("Cookie", "FSSBBIl1UgzbN7N80S=Rn6bUXG._C51qF149owJv8imbiiiSUoM4MK5bbdhSuZVZyNKPNlC6lIhWhsl3H9h; orgNo=51101; orgName=%E6%80%BB%E7%AB%99; CSWEBSID=gdZ6cw3fhKdbHTdJvcQvy23JqJVd24wT!-1312484030; cookie-web=58554222; _pk_ref.4.9c8b=%5B%22%22%2C%22%22%2C1559295440%2C%22http%3A%2F%2Fwww.sc.sgcc.com.cn%2Fdy%2F%22%5D; _pk_id.4.9c8b=8e5d45506d56d77e.1559285598.2.1559295440.1559289288.; FSSBBIl1UgzbN7N80T=3ZFmYA_ExkutSUxdxhNrwntohPLCcFGpkj1PEKLSTK.M10v3vvRL57rr448jv_NqfaHNMTPLj7SjE2hd5y5Hno0cLNlhijRt5.rFkN2YjnczY7UI04e7LsvVP4sTM0RYSVGunXjFiSt_BU3AZX6HyYTt4QC_D76jGMYEAi8eMVvGya6K1I.p8TrlMYiU9_CGoufyFRYpx78WT1FvMLgdEu55DvpgO0bF7dFmGRqoMkOtaL8cGEzAGgq9KcBtpC.OCMX3vGHs4UNmBgLzRyaqDoWhGfXflhCbPnxYD_DRYw17Gm9vbs_IX5Ogt_EBRi4aO_gAg2DRDu4by3TinfRe6cXNHl2WOnfqLTbEDvf8G_ng9qG; cookie-webcc=37132023");


            // 将上面的配置信息 运用到这个Get请求里
            httpGet.setConfig(requestConfig);
            // 由客户端执行(发送)Get请求
            response = httpClient.execute(httpGet);
            int state = response.getStatusLine().getStatusCode();
            System.out.println("状态码：" + state);

            // 从响应模型中获取响应实体
            HttpEntity responseEntity = response.getEntity();
            System.out.println("响应状态为:" + response.getStatusLine());
            if (responseEntity != null) {
                System.out.println("响应内容长度为:" + responseEntity.getContentLength());
                result = EntityUtils.toString(responseEntity, "UTF-8");
                System.out.println("编码格式：" + responseEntity.getContentType().getValue());
                System.out.println("响应内容为:" + result);
            }
        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (ParseException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            handleResource(httpClient, response);
            return result;
        }
    }


    private static String doPost(String url, String urlParam) {
        // 创建Post请求
        HttpPost httpPost = new HttpPost((url.startsWith("http") ? url : "http://" + url) + "?" + urlParam);
        // 设置ContentType(注:如果只是传普通参数的话,ContentType不一定非要用application/json)
        return gePostResult(httpPost, false);
    }

    private static String doPostJson(String url, String urlParam) {
        // 创建Post请求
        HttpPost httpPost = new HttpPost((url.startsWith("http") ? url : "http://" + url) + "?" + urlParam);
        // 设置ContentType(注:如果只是传普通参数的话,ContentType不一定非要用application/json)
        return gePostResult(httpPost, true);
    }

    private static String doPost(String url, Map<String, Object> paramsMap) {
        // 创建Post请求
        HttpPost httpPost = new HttpPost(url.startsWith("http") ? url : "http://" + url);
        //装配post请求参数
        List<NameValuePair> list = new ArrayList<>();
        for (String key : paramsMap.keySet()) {
            list.add(new BasicNameValuePair(key, String.valueOf(paramsMap.get(key))));
        }
        UrlEncodedFormEntity urlEncodedFormEntity = null;
        try {
            urlEncodedFormEntity = new UrlEncodedFormEntity(list, "utf-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        // post请求是将参数放在请求体里面传过去的;这里将entity放入post请求体中
        httpPost.setEntity(urlEncodedFormEntity);
        return gePostResult(httpPost, false);
    }

    private static String doPostJson(String url, JSONObject jsonObject) {
        // 创建Post请求
        HttpPost httpPost = new HttpPost(url.startsWith("http") ? url : "http://" + url);
        //解决中文乱码问题
        StringEntity entity = new StringEntity(jsonObject.toString(),"utf-8");
        httpPost.setEntity(entity);
        return gePostResult(httpPost, true);
    }

    /**
     * 功能描述: 获取post连接结果
     *
     * @param
     * @return
     * @throws
     * @author hugo
     * @date 2019/5/8 22:50
     */
    private static String gePostResult(HttpPost httpPost, boolean json) {
        // 获得Http客户端(可以理解为:你得先有一个浏览器;注意:实际上HttpClient与浏览器是不一样的)
        CloseableHttpClient httpClient = HttpClientBuilder.create().build();
        String header = json ? "application/json;charset=utf8" : "application/x-www-form-urlencoded";
        httpPost.setHeader("Content-Type", header);
        // 响应模型
        CloseableHttpResponse response = null;
        String result = "";
        try {
            // 由客户端执行(发送)Post请求
            response = httpClient.execute(httpPost);
            // 从响应模型中获取响应实体
            HttpEntity responseEntity = response.getEntity();
            System.out.println("响应状态为:" + response.getStatusLine());
            if (responseEntity != null) {
                System.out.println("响应内容长度为:" + responseEntity.getContentLength());
                result = EntityUtils.toString(responseEntity, "UTF-8");
                System.out.println("响应内容为 :" + result);
            }
        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (ParseException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            handleResource(httpClient, response);
            return result;
        }
    }

    private static void handleResource(CloseableHttpClient httpClient, CloseableHttpResponse response) {
        if (httpClient != null) {
            try {
                httpClient.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        //  释放资源
        if (response != null) {
            try {
                response.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    private static String map2String(Map<String, Object> params) {
        StringBuffer result = new StringBuffer();
        try {
            for (Map.Entry<String, Object> map : params.entrySet()) {
                // 字符数据最好encoding以下;这样一来，某些特殊字符才能传过去(如:某人的名字就是“&”,不encoding的话,传不过去)
                result.append(map.getKey()).append("=").append(URLEncoder.encode((String) map.getValue(), "utf-8")).append("&");
            }
        } catch (UnsupportedEncodingException e1) {
            e1.printStackTrace();
        }
        return result.toString().substring(0, result.toString().length() - 1);
    }


}